.globl write_matrix

.text
# ==============================================================================
# FUNCTION: Writes a matrix of integers into a binary file
#   If any file operation fails or doesn't write the proper number of bytes,
#   exit the program with exit code 1.
# FILE FORMAT:
#   The first 8 bytes of the file will be two 4 byte ints representing the
#   numbers of rows and columns respectively. Every 4 bytes thereafter is an
#   element of the matrix in row-major order.
# Arguments:
#   a0 (char*) is the pointer to string representing the filename
#   a1 (int*)  is the pointer to the start of the matrix in memory
#   a2 (int)   is the number of rows in the matrix
#   a3 (int)   is the number of columns in the matrix
# Returns:
#   None
#
# If you receive an fopen error or eof,
# this function exits with error code 53.
# If you receive an fwrite error or eof,
# this function exits with error code 54.
# If you receive an fclose error or eof,
# this function exits with error code 55.
# ==============================================================================
write_matrix:

    # Prologue
    addi sp, sp, -20
    sw ra, 0(sp)
    sw s0, 4(sp)
    sw s1, 8(sp)
    sw s2, 12(sp)
    sw s3, 16(sp)

    # save arguments
    add s1, a1, x0 # pointer to matrix in mem
    add s2, a2, x0 # rows
    add s3, a3, x0 # columns

    # open file
    add a1, a0, x0 # string filename (char *)
    addi a2, x0, 1 # set read permission '1'
    jal ra, fopen

    addi t0, x0, -1
    # if file descriptor != -1, goto file_read
    bne a0, t0, write_dim
    addi a1, x0, 53
    jal ra, exit2

write_dim:
    # save file descriptor
    add s0, a0, x0

    addi sp, sp, -8
    sw s2, 0(sp)
    sw s3, 4(sp)
    # write row and col
    add a1, s0, x0
    add a2, sp, x0
    addi a3, x0, 2
    addi a4, x0, 4
    jal ra, fwrite

    addi sp, sp, 8
    # if a0 == a3, goto write_data
    beq a0, a3, write_data
    addi a1, x0, 54
    jal ra, exit2

write_data:
    # write data
    add a1, s0, x0
    add a2, s1, x0
    mul a3, s2, s3
    addi a4, x0, 4
    jal ra, fwrite
    # if a0 == a3, goto file_close
    beq a0, a3, file_close
    addi a1, x0, 54
    jal ra, exit2

file_close:
    # close the file
    add a1, s0, x0
    jal ra, fclose
    # if a0 == x0, goto end
    beq a0, x0, end
    addi a1, x0, 55
    jal ra, exit2

end:
    # Epilogue
    lw ra, 0(sp)
    lw s0, 4(sp)
    lw s1, 8(sp)
    lw s2, 12(sp)
    lw s3, 16(sp)
    addi sp, sp, 20

    ret
